home *** CD-ROM | disk | FTP | other *** search
-
- #include <exec/libraries.h>
- #include <stdlib.h>
- #include <exec/types.h>
- #include <proto/gadtools.h>
- #include <libraries/gadtools.h>
- #include <proto/intuition.h>
- #include <intuition/intuition.h>
- #include <proto/graphics.h>
- #include <graphics/text.h>
- #include <string.h>
- #include <intuition/gadgetclass.h>
-
- #define GL_VBOX -1
- #define GL_HBOX -2
- #define CUSTOM_KIND -3
-
- #define MODE_NEW 0
- #define MODE_RESIZE 1
- #define MODE_REFRESH 2
- #define MODE_FREE 3
- #define MODE_BACKUP 4
- #define MODE_RESTORE 5
-
- #define BOXFLG_CUSTOM 1
- #define BOXFLG_STRING 2
- #define BOXFLG_INTEGER 4
- #define BOXFLG_DISABLED 8
- #define BOXFLG_BACKUP 16
- #define BOXFLG_INITED (1<<15)
- #define BOXFLG_SKIPREFRESH (1<<14)
-
- #define max(x,y) ((x)>(y)?(x):(y))
- #define min(x,y) ((x)<(y)?(x):(y))
-
- struct GadDim {
- int Kind;
- USHORT Rx,Ry,Cx,Cy,Px,Py,SRx,SRy,SPx,SPy;
- USHORT Flags;
- };
-
- struct Box {
- struct GadDim Dim;
- struct Box **Entry;
- };
-
- struct WinInfo {
- struct Box *Box;
- struct Gadget **Gadgets;
- struct Gadget *Prev;
- struct Window *Window;
- struct Gadget *GList;
- int FontX,FontY;
- struct TextAttr TextAttr;
- APTR Visual;
- char Mode,Render;
- // USHORT MinX,MinY;
- };
-
- struct GadInfo {
- struct GadDim Dim;
- int XSpace,YSpace,GadNum;
- int (*CustomFunc)(struct WinInfo *WInfo,
- struct NewGadget *NewGad,
- struct GadInfo *GadInfo,
- int Left, int Top, int Width, int Height);
- struct TextAttr *TextAttr;
- char *Text;
- int GadgetID;
- ULONG Flags,UserData;
- int (*HookFunc)(struct IntuiMessage *);
- ULONG *Tags;
- ULONG *SaveTags;
- ULONG Code;
- struct Gadget *ThisGad;
- };
-
- #define GetString(g) (((struct StringInfo * )g->SpecialInfo)->Buffer)
- #define GetNumber(g) (((struct StringInfo * )g->SpecialInfo)->LongInt)
- #define GetInfo(g) ((struct GadInfo *)(g->UserData))
- #define GetUserData(g) (GetInfo(g)->UserData)
-
- ULONG Modify[]={0,0,GTCB_Checked,GTIN_Number,GTLV_Selected,
- GTMX_Active,0,GTCY_Active,GTPA_Color,
- GTSC_Top,0,GTSL_Level,GTST_String,0};
-
- ULONG Default[]={0,0,FALSE,0,~0,0,0,0,1,0,0,0,(ULONG)"",0};
-
- static ULONG *MergeTags(ULONG *oldlist,ULONG *newlist)
- {
- ULONG *p;
- if(!oldlist) {
- oldlist=malloc(16*sizeof(ULONG));
- if(!oldlist) return(NULL);
- oldlist[0]=16;
- oldlist[1]=TAG_DONE;
- }
-
- while(*newlist!=TAG_DONE) {
- switch(*newlist) {
- case TAG_IGNORE: newlist+=2;
- break;
- case TAG_MORE: newlist=(ULONG *)newlist[1];
- break;
- case TAG_SKIP: newlist+=2*newlist[1]+2;
- break;
- default:
-
- p=oldlist+1;
- /* passenden Eintrag in der Taglist suchen, bzw Ende der Liste */
- while(*p!=TAG_DONE && *p!=*newlist) p+=2;
- if(*p==*newlist) {
- p[1]=newlist[1]; // alte Daten ueberschreiben
- newlist+=2;
- } else {
- int n=p-oldlist; // Position im Array;
-
- if(n>=oldlist[0]-1) { // Array vergrößern
- ULONG *mem;
- mem=realloc(oldlist,oldlist[0]+16*sizeof(ULONG));
- if(!mem) return(NULL);
- oldlist=mem;
- p=oldlist+n;
- }
-
- *p++=*newlist++;
- *p++=*newlist++;
- *p++=TAG_DONE;
- }
- break;
- }
- }
- return(oldlist);
- }
-
- BOOL Gui_SetGadgetAttrsA(struct Gadget *gad,struct Window *win,
- struct Requester *req, ULONG *Tag)
- {
- ULONG *newtags;
- struct GadInfo *gi;
-
- gi=GetInfo(gad);
-
- if(!gi->SaveTags) {
- gi->SaveTags=MergeTags(NULL,gi->Tags);
- if(!gi->SaveTags) return(FALSE);
- }
-
- newtags=MergeTags(gi->SaveTags,Tag);
- if(!newtags) return(FALSE);
- gi->SaveTags=newtags;
- GT_SetGadgetAttrsA(gad,win,req,(struct TagItem *)Tag);
- return(TRUE);
- }
- BOOL Gui_SetGadgetAttrs(struct Gadget *gad,struct Window *win,
- struct Requester *req, ULONG Tag1,...)
- {
- return(Gui_SetGadgetAttrsA(gad,win,req,&Tag1));
- }
-
- int MakeGTGadget(struct WinInfo *winfo, ///
- struct GadInfo *gad,
- int left, int top, int width, int height)
- {
- struct NewGadget ng;
-
- if(winfo->Mode==MODE_REFRESH && gad->Dim.Kind>=0) return(0);
-
- ng.ng_LeftEdge=left + (gad->XSpace>>1);
- ng.ng_TopEdge=top + (gad->YSpace>>1);
- ng.ng_Width=width - gad->XSpace;
- ng.ng_Height=height - gad->YSpace;
- ng.ng_GadgetText=gad->Text;
- ng.ng_TextAttr=gad->TextAttr ? gad->TextAttr : &winfo->TextAttr;
- ng.ng_GadgetID=gad->GadgetID;
- ng.ng_Flags=gad->Flags;
- ng.ng_VisualInfo=winfo->Visual;
- ng.ng_UserData=(void *)gad;
-
- gad->Dim.Flags|=BOXFLG_INITED;
-
- if(gad->Dim.Kind>=0) {
- // Falls dies kein erneutes aufsetzen ist: SaveTags neu errechnen
- if(!(winfo->Box->Dim.Flags & BOXFLG_BACKUP) && winfo->Mode==MODE_NEW) {
- ULONG *tags;
- static ULONG modifytag[]={0,0,TAG_DONE};
-
- if(gad->SaveTags) free(gad->SaveTags);
- gad->SaveTags=NULL;
-
- if(Modify[gad->Dim.Kind]) {
- modifytag[0]=Modify[gad->Dim.Kind];
- modifytag[1]=Default[gad->Dim.Kind];
- tags=MergeTags(NULL,modifytag);
- if(!tags) return(1);
- gad->SaveTags=tags;
- }
- tags=MergeTags(gad->SaveTags,gad->Tags);
- if(!tags) return(1);
- gad->SaveTags=tags;
- }
-
- winfo->Prev=gad->ThisGad=winfo->Gadgets[gad->GadNum]=
- CreateGadgetA(gad->Dim.Kind,winfo->Prev,&ng,(struct TagItem *)(gad->SaveTags+1));
- if(winfo->Prev==NULL) return(1); else return(0);
- } else {
- return(gad->CustomFunc(winfo,&ng,gad,left,top,width,height));
- }
- } ///
- static int MakeGuiGadget(struct WinInfo *winfo, ///
- struct Box *box,
- int left,int top,int width,int height)
- {
- struct Box **p;
- int relx=0,rely=0,absx=0,absy=0;
- int w,h;
-
- if(box->Dim.Kind>0 || box->Dim.Kind==CUSTOM_KIND)
- return(MakeGTGadget(winfo,(struct GadInfo *)box,
- left,top,width,height));
-
- if(!box->Entry) return(0);
-
- relx=box->Dim.SRx;
- rely=box->Dim.SRy;
- absx=box->Dim.SPx;
- absy=box->Dim.SPy;
-
- if(!winfo->Render) {
- for(p=box->Entry;*p;p++) {
- if(MakeGuiGadget(winfo,(*p),0,0,0,0)) return(1);
- }
- } else {
- if(box->Dim.Kind==GL_HBOX) {
-
- width-=absx;
- if(width<0) width=0;
-
- for(w=0,p=box->Entry;*p;p++) {
- w=width * ((*p)->Dim.Rx)/relx + (*p)->Dim.Px;
- h=height * ((*p)->Dim.Ry)/rely + (*p)->Dim.Py;
-
- if(MakeGuiGadget(winfo,(*p),left,top,w,h)) return(1);
-
- left+=w;
- }
-
- } else {
-
- height-=absy;
- if(height<0) height=0;
-
- for(w=0,p=box->Entry;*p;p++) {
- w=width * ((*p)->Dim.Rx)/relx + (*p)->Dim.Px;
- h=height * ((*p)->Dim.Ry)/rely + (*p)->Dim.Py;
-
- if(MakeGuiGadget(winfo,(*p),left,top,w,h)) return(1);
-
- top+=h;
- }
-
- }
- }
- return(0);
- } ///
-
- static void InitGui(struct WinInfo *winfo,struct Box *box) ///
- {
- struct Box **p;
- int relx=0,rely=0,absx=0,absy=0;
-
- box->Dim.Px+=box->Dim.Cx*winfo->FontX;
- box->Dim.Py+=box->Dim.Cy*winfo->FontY;
- box->Dim.Cx=0;
- box->Dim.Cy=0;
-
- if(!box->Entry || box->Dim.Kind>0 || box->Dim.Kind==CUSTOM_KIND) {
- return;
- }
-
- for(p=box->Entry;*p;p++) InitGui(winfo,*p);
-
- if(box->Dim.Kind==GL_HBOX) {
-
- for(p=box->Entry;*p;p++) {
- relx+=(*p)->Dim.Rx;
- absx+=(*p)->Dim.Px;
-
- rely=max(rely,(*p)->Dim.Ry);
- absy=max(absy,(*p)->Dim.Py);
- }
- } else {
- for(p=box->Entry;*p;p++) {
- rely+=(*p)->Dim.Ry;
- absy+=(*p)->Dim.Py;
-
- relx=max(relx,(*p)->Dim.Rx);
- absx=max(absx,(*p)->Dim.Px);
- }
- }
-
- if(relx==0) relx=1;
- if(rely==0) rely=1;
-
- box->Dim.SRx=relx;
- box->Dim.SRy=rely;
- box->Dim.SPx=absx;
- box->Dim.SPy=absy;
-
- box->Dim.Flags=BOXFLG_INITED;
- for(p=box->Entry;*p;p++) {
- box->Dim.Flags|=(*p)->Dim.Flags;
- }
-
- return;
- } ///
- static int BackupGui(struct WinInfo *winfo,struct Box *box) ///
- {
- struct GadInfo *gad=(struct GadInfo *)box;
- int err=0;
-
- if(box->Dim.Flags & (BOXFLG_STRING | BOXFLG_INTEGER)) {
-
- if(box->Dim.Kind==INTEGER_KIND) {
- ULONG tags[]={GTIN_Number,0,TAG_DONE};
- tags[1]=GetNumber(gad->ThisGad);
- MergeTags(gad->SaveTags,tags);
- // gad->Code=GetNumber(gad->ThisGad);
- } else if(box->Dim.Kind==STRING_KIND) {
- ULONG tags[]={GTST_String,0,TAG_DONE};
- if(gad->Code) free((void *)gad->Code);
- gad->Code=(ULONG)strdup(GetString(gad->ThisGad));
- if(!gad->Code) return(1);
- tags[1]=gad->Code;
- MergeTags(gad->SaveTags,tags); // This is always successful, since
- // there is always a GTST_String tag
- // in the taglist (see MakeGTGadget)
- } else if(box->Dim.Kind==GL_VBOX || box->Dim.Kind==GL_HBOX) {
- struct Box **p;
-
- if(!box->Entry) return(0);
-
- for(p=box->Entry; *p; p++) {
- err|=BackupGui(winfo,*p);
- }
- }
- }
- return(err);
- } ///
- static void FindCustom(struct WinInfo *winfo,struct Box *box) ///
- {
- struct GadInfo *gad=(struct GadInfo *)box;
- static struct NewGadget ng; /* Just to avoid Enforcer Hits */
-
- if( !(box->Dim.Flags & BOXFLG_CUSTOM)) return;
-
- if(box->Dim.Kind==CUSTOM_KIND) {
- gad->CustomFunc(winfo,&ng,gad,0,0,0,0);
- } else if(box->Dim.Kind==GL_VBOX || box->Dim.Kind==GL_HBOX) {
- struct Box **p;
-
- if(box->Dim.Flags & BOXFLG_CUSTOM) {
- if(!box->Entry) return;
-
- for(p=box->Entry; *p; p++) {
- FindCustom(winfo,*p);
- }
- }
- }
- } ///
-
- struct IntuiMessage *Gui_GetIMsg(struct MsgPort *userport,struct IntuiMessage *imsg) ///
- {
- struct IntuiMessage *msg;
- int ignore=0;
- struct Gadget *gad;
-
- if(msg=GT_GetIMsg(userport)) {
- *imsg=*msg;
- GT_ReplyIMsg(msg);
-
- switch(imsg->Class) {
- case IDCMP_MOUSEMOVE:
- case IDCMP_GADGETUP:
- case IDCMP_GADGETDOWN:
- gad=(struct Gadget *)imsg->IAddress;
- if(gad && gad->GadgetID>=0) {
- struct GadInfo *gi;
- ULONG tags[]={0,0,TAG_DONE};
- gi=GetInfo(gad);
-
- if(Modify[gi->Dim.Kind]) {
- tags[0]=Modify[gi->Dim.Kind];
- tags[1]=imsg->Code;
- MergeTags(gi->SaveTags,tags); //always successful in this case
- }
- if(GetInfo(gad)->HookFunc) ignore=GetInfo(gad)->HookFunc(imsg);
- }
- break;
- }
- if(!ignore) return(imsg);
- }
- return(NULL);
- } ///
-
- void ClearWindow(struct Window *win)
- {
- RefreshWindowFrame(win);
- EraseRect(win->RPort,win->BorderLeft,
- win->BorderTop,
- win->Width-1-win->BorderRight,
- win->Height-1-win->BorderBottom);
- }
-
- int RenderGui(struct Window *win, struct WinInfo *winfo) ///
- {
- winfo->Window=win;
- winfo->Mode=MODE_NEW;
- winfo->Render=1;
-
- AskFont(win->RPort,&winfo->TextAttr);
-
- winfo->FontX = win->RPort->Font->tf_XSize;
- winfo->FontY = win->RPort->Font->tf_YSize;
- winfo->Visual=GetVisualInfoA(win->WScreen,NULL);
-
- if(!(winfo->Box->Dim.Flags & BOXFLG_INITED)) {
- InitGui(winfo,winfo->Box);
- winfo->Box->Dim.Flags|=BOXFLG_INITED;
- }
-
- if(!winfo->Visual) goto exit_fail2;
-
- if(!CreateContext(&winfo->GList)) return(1);
-
- winfo->Prev=winfo->GList;
-
- if(MakeGuiGadget(winfo,winfo->Box,win->BorderLeft,win->BorderTop,
- win->Width - win->BorderLeft - win->BorderRight,
- win->Height - win->BorderTop - win->BorderBottom))
- goto exit_fail3;
- AddGList(win,winfo->GList,-1,-1,NULL);
- RefreshGList(winfo->GList,win,NULL,-1);
- GT_RefreshWindow(win,NULL);
-
- if(winfo->Box->Dim.Flags & BOXFLG_BACKUP) {
- winfo->Mode=MODE_RESTORE;
- FindCustom(winfo,winfo->Box);
- winfo->Box->Dim.Flags &= ~BOXFLG_BACKUP;
- }
-
- return(0);
-
- exit_fail3:
- if(winfo->GList) FreeGadgets(winfo->GList);
- FreeVisualInfo(winfo->Visual);
- exit_fail2:
- return(1);
- } ///
- int ResizeGui(struct WinInfo *winfo) ///
- {
- struct Window *win=winfo->Window;
-
- winfo->Box->Dim.Flags|=BOXFLG_SKIPREFRESH;
- winfo->Mode=MODE_BACKUP;
- winfo->Render=0;
-
- ClearWindow(win);
-
- FindCustom(winfo,winfo->Box); // Backup od customgadgets
-
- BackupGui(winfo,winfo->Box);
-
- winfo->Mode=MODE_RESIZE;
- winfo->Render=1;
-
- if(winfo->GList) {
- RemoveGList(win,winfo->GList,-1);
- FreeGadgets(winfo->GList);
- }
- winfo->GList=NULL;
-
- ClearWindow(win);
-
- if(!CreateContext(&winfo->GList)) return(1);
- winfo->Prev=winfo->GList;
-
- if(MakeGuiGadget(winfo,winfo->Box,win->BorderLeft,win->BorderTop,
- win->Width - win->BorderLeft - win->BorderRight,
- win->Height - win->BorderTop - win->BorderBottom))
- return(2);
-
- AddGList(win,winfo->GList,-1,-1,NULL);
- RefreshGList(winfo->GList,win,NULL,-1);
- GT_RefreshWindow(win,NULL);
- winfo->Mode=MODE_RESTORE;
- winfo->Render=0;
- FindCustom(winfo,winfo->Box);
- return(0);
- } ///
- int RefreshGui(struct WinInfo *winfo) ///
- {
- struct Window *win=winfo->Window;
-
- if(winfo->Box->Dim.Flags&BOXFLG_SKIPREFRESH) {
- winfo->Box->Dim.Flags&=~BOXFLG_SKIPREFRESH;
- return(0);
- }
-
- winfo->Render=1;
- winfo->Mode=MODE_REFRESH;
- if(MakeGuiGadget(winfo,winfo->Box,win->BorderLeft,win->BorderTop,
- win->Width - win->BorderLeft - win->BorderRight,
- win->Height - win->BorderTop - win->BorderBottom)) return(1);
-
- RefreshGList(winfo->GList,win,NULL,-1);
- GT_RefreshWindow(winfo->Window,NULL);
- return(0);
- } ///
-
- static void FreeStopGui(struct WinInfo *winfo,int backup) ///
- {
- winfo->Render=0;
- if(backup) {
- winfo->Mode=MODE_BACKUP;
- FindCustom(winfo,winfo->Box);
- winfo->Box->Dim.Flags|=BOXFLG_BACKUP;
- }
- winfo->Mode=MODE_FREE;
- FindCustom(winfo,winfo->Box);
-
- if(winfo->GList) {
- RemoveGList(winfo->Window,winfo->GList,-1);
- FreeGadgets(winfo->GList);
- }
- FreeVisualInfo(winfo->Visual);
- } ///
- void FreeGui(struct WinInfo *winfo)
- {
- FreeStopGui(winfo,0);
- }
- void StopGui(struct WinInfo *winfo)
- {
- FreeStopGui(winfo,1);
- }
-
- int RenderSubGui(struct WinInfo *winfo, ///
- int left,int top,int width, int height)
- {
- if(!(winfo->Box->Dim.Flags & BOXFLG_INITED)) {
- InitGui(winfo,winfo->Box);
- winfo->Box->Dim.Flags|=BOXFLG_INITED;
- }
- if(MakeGuiGadget(winfo,winfo->Box,left,top,width,height)) return(1);
-
- return(0);
- } ///
- int ResizeSubGui(struct WinInfo *winfo, ///
- int left, int top,int width,int height)
- {
- if(MakeGuiGadget(winfo,winfo->Box,left,top,width,height)) return(1);
-
- return(0);
- } ///
- int RefreshSubGui(struct WinInfo *winfo,int left,int top,int width,int height) ///
- {
- winfo->Mode=MODE_REFRESH;
- return(MakeGuiGadget(winfo,winfo->Box,left,top,width,height));
- } ///
- void FreeSubGui(struct WinInfo *winfo) ///
- {
- winfo->Mode=MODE_FREE;
- FindCustom(winfo,winfo->Box);
- } ///
-
- int SubGui(struct WinInfo *parent, struct WinInfo *winfo, ///
- int left,int top,int width, int height)
- {
- int ret=0;
-
- memcpy((void *)(((ULONG)winfo)+2*sizeof(void *)),
- (void *)(((ULONG)parent)+2*sizeof(void *)),
- sizeof(struct WinInfo)-2*sizeof(void *));
-
- switch(parent->Mode) {
-
- case MODE_NEW: ret=RenderSubGui(winfo,left,top,width,height);
- winfo->Box->Dim.Flags&=~BOXFLG_BACKUP;
- break;
- case MODE_RESIZE: ret=ResizeSubGui(winfo,left,top,width,height);
- winfo->Box->Dim.Flags&=~BOXFLG_BACKUP;
- break;
- case MODE_REFRESH: ret=RefreshSubGui(winfo,left,top,width,height);
- break;
- case MODE_FREE: FreeSubGui(winfo);
- break;
- case MODE_RESTORE:
- FindCustom(winfo,winfo->Box);
- break;
- case MODE_BACKUP: ret=BackupGui(winfo,winfo->Box);
- FindCustom(winfo,winfo->Box);
- winfo->Box->Dim.Flags|=BOXFLG_BACKUP;
- break;
- }
- parent->Prev=winfo->Prev;
- return(ret);
- } ///
-